package org.mclll.xwangplugin.town.tax;

import de.tr7zw.nbtapi.NBT;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import org.mclll.xwangplugin.MclllCustom;
import org.mclll.xwangplugin.town.config.TownConfig;
import org.mclll.xwangplugin.town.database.domain.TownDO;
import org.mclll.xwangplugin.town.database.domain.TownTaxRecordDO;
import org.mclll.xwangplugin.town.database.mapper.manage.TownManage;
import org.mclll.xwangplugin.town.database.mapper.manage.TownTaxRecordManage;
import org.mclll.xwangplugin.town.enums.TownLevel;
import org.mclll.xwangplugin.util.PlayerTools;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;

import static org.mclll.xwangplugin.town.config.TownContext.*;

public class TownTax {
    private MclllCustom plugin;
    public TownTax(MclllCustom plugin) {
        this.plugin = plugin;
    }
    public void taxCheck() {
        List<TownDO> townList = TownManage.selectList(new TownDO());
        for (TownDO town : townList) {
            if (town.getTownLevel() == TownLevel.DUST) {
                continue;
            }
            LocalDateTime lastTaxTime = town.getLastTaxTime();
            LocalDateTime now = LocalDateTime.now();
            Duration between = Duration.between(lastTaxTime, now);
            long days = between.toDays();
            if (days <= TownConfig.GET_TAX_DAYS - 3) {
                continue;
            }
            OfflinePlayer leader = PlayerTools.getOfflineOrOnlinePlayerByUuid(town.getLeaderUuid());
            int num = town.getTownLevel().totalTax() - town.getMonthTax();
            if (days <= TownConfig.REMINDER_TAXES_DAYS_ADVANCE && num > 0) {
                if (leader.isOnline()) {
                    ((Player)leader).sendMessage(String.format(TOWN_TAX_ALERT, num));
                }
                return;
            }
            // 税收日到了
            if (days >= TownConfig.GET_TAX_DAYS) {
                TownDO updateParam = new TownDO();
                updateParam.setUuid(town.getUuid());
                // 说明税收不够城镇降级
                if (num > 0) {
                    // 降级
                    updateParam.setTownLevel(town.getTownLevel().lastLevel());
                    Bukkit.getScheduler().runTask(plugin, () -> {
                        Server server = Bukkit.getServer();
                        ConsoleCommandSender sender = Bukkit.getConsoleSender();
                        for (int i = 0; i < 3; i++) {
                            server.dispatchCommand(sender, "say " + String.format(NOW_TOWN_LEVEL_DOWN, town.getName()));
                        }
                    });
                } else {
                    // 征税!!!
                    updateParam.setMonthTax(num == 0 ? 0 : -1 * num);
                    updateParam.setLastTaxTime(now);
                }
                TownManage.updateByUuid(updateParam);
            }
        }
    }

    public static boolean submitTax(Player player, TownDO town, int count) {
        int taxCount = count;
        @Nullable ItemStack[] contents = player.getInventory().getContents();
        for (int i = 0; i < contents.length; i++) {
            ItemStack item = contents[i];
            if (item == null || item.getType() == Material.AIR) {
                continue;
            }
            String mythicType = NBT.get(item, nbt -> {
                return nbt.getString("MYTHIC_TYPE");
            });
            if (!"心之石".equals(mythicType)) {
                continue;
            }
            if (item.getAmount() >= taxCount) {
                if (item.getAmount() == taxCount) {
                    contents[i] = null;
                } else {
                    item.setAmount(item.getAmount() - taxCount);
                }
                player.getInventory().setContents(contents);
                TownDO updateParam = new TownDO();
                updateParam.setUuid(town.getUuid());
                updateParam.setTotalTax(town.getTotalTax() + count);
                updateParam.setMonthTax(town.getMonthTax() + count);
                TownManage.updateByUuid(updateParam);
                TownTaxRecordDO townTaxRecord = new TownTaxRecordDO();
                townTaxRecord.setTaxNum(count);
                townTaxRecord.setTownUuid(town.getUuid());
                townTaxRecord.setPlayerUuid(player.getUniqueId().toString());
                TownTaxRecordManage.insert(townTaxRecord);
                return true;
            } else {
                taxCount -= item.getAmount();
                contents[i] = null;
            }
        }
        return false;
    }
}
